/*
 * Copyright (C) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <aki/jsbind.h>
#include <chrono>
#include <thread>

void Foo() {}

// AsyncTaskReturnInt: 异步调用,阻塞1后返回int值
int AsyncTaskReturnInt() {
    std::this_thread::sleep_for(std::chrono::seconds(1)); // 工作线程 sleep 1 秒
    return 1;
}

// 绑定枚举类
enum ColorType {
    NONE,
    YELLOW,
    WHITE,
    BLACK,
    END,
};

// 绑定Human类
struct Human {
public:
    Human(std::string name) : name_(name) {}
    std::string GetName() const {return name_; }
    std::string DoTask() {
        std::this_thread::sleep_for(std::chrono::seconds(1));
        return "done";
    }
    ColorType color_type;
private:
    std::string name_;
};

bool PassingNoneReturnBool()
{
    return true;
}

std::string PassingStringReturnString(std::string str)
{
    return str;
}

void PassingFunctionReturnVoid(std::function<void ()> func)
{
    func();
}

void PassingCallbackReturnVoid(aki::Callback<void ()> func)
{
    func();
}

void PassingSafetyCallbackReturnVoid(aki::SafetyCallback<void ()> func)
{
    func();
}

static std::string CallJsFunc(std::string name)
{
    std::string res = "";
    if(auto func = aki::JSBind::GetJSFunction(name)) {
        res = func->Invoke<std::string>();
    } else {
        AKI_LOG(ERROR) << "GetJSFunction " << name << " failed";
    }
    return res;
}


JSBIND_ENUM(ColorType) {
    JSBIND_ENUM_VALUE(NONE);
    JSBIND_ENUM_VALUE(YELLOW);
    JSBIND_ENUM_VALUE(WHITE);
    JSBIND_ENUM_VALUE(BLACK);
    JSBIND_ENUM_VALUE(END);
}

JSBIND_CLASS(Human) {
    JSBIND_CONSTRUCTOR<std::string>();
    JSBIND_METHOD(GetName); // 绑定同步方法
    JSBIND_PMETHOD(DoTask); // 绑定异步方法
    JSBIND_PROPERTY(color_type);  // 绑定成员属性
}

JSBIND_GLOBAL() {
    JSBIND_FUNCTION(Foo);
    JSBIND_FUNCTION(CallJsFunc);
    JSBIND_PFUNCTION(AsyncTaskReturnInt);
    JSBIND_FUNCTION(PassingNoneReturnBool);
    JSBIND_FUNCTION(PassingStringReturnString);
    JSBIND_FUNCTION(PassingFunctionReturnVoid);
    JSBIND_FUNCTION(PassingCallbackReturnVoid);
    JSBIND_FUNCTION(PassingSafetyCallbackReturnVoid);
}

JSBIND_ADDON(hello);